﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI.WebControls.WebParts;
using System.Reflection;
using System.Web.UI.WebControls;
using System.Web;
using System.Web.UI;

namespace UserControlHostingWebPartSolution
{
    public class UserControlHostingParametersEditorPart : EditorPart
    {
        public UserControlHostingParametersEditorPart()
        {
            ID = "UserControlHostingParametersEditorPart";
        }

        private Dictionary<string, Control> pvtbs = new Dictionary<string, Control>();

        private bool CanChangeType(Type sourceType, Type targetType)
        {
            if (sourceType.Equals(targetType)) return true;
            try
            {
                var instanceOfSourceType = Activator.CreateInstance(sourceType);
                Convert.ChangeType(instanceOfSourceType, targetType);
                return true; // OK, it can be converted 
            }
            catch (Exception ex)
            {
                return false;
            }
        }

        protected override void CreateChildControls()
        {
            UserControlHostingWebPart webpart = (UserControlHostingWebPart)this.WebPartToEdit;
            if (webpart.hostedcontrol != null)
            {
                Table sectionTableXsl;
                Control sectionXsl = EditorPartHelper.createConfigureSectionControls(this, "Expand Category: UserControl Properties", "Collapse Category: UserControl Properties", "UserControl Properties", "UserControlProperties", "", out sectionTableXsl);
                Controls.Add(sectionXsl);


                Table propertiestable = new Table();
                Controls.Add(propertiestable);

                Type hostedcontroltype = webpart.hostedcontrol.GetType();
                PropertyInfo[] properties = hostedcontroltype.GetProperties();
                foreach (PropertyInfo pi in properties)
                {
                    if (CanChangeType(pi.PropertyType, typeof(string)) && pi.CanWrite)
                    {
                        string ctrlID = "ctrl" + pi.Name;
                        if (pi.PropertyType == typeof(bool))
                        {
                            CheckBox cbPropertyValue = new CheckBox();
                            cbPropertyValue.ID = ctrlID;
                            cbPropertyValue.CssClass = "UserInput";
                            cbPropertyValue.Checked = (bool)pi.GetValue(webpart.hostedcontrol, null);
                            EditorPartHelper.addToolPaneControl(sectionTableXsl, pi.Name + " (" + pi.PropertyType.Name + ")", cbPropertyValue, false);
                            pvtbs.Add(pi.Name, cbPropertyValue);

                            try
                            {
                                if (webpart.PropertyValuesCollection.ContainsKey(pi.Name))
                                {
                                    cbPropertyValue.Checked = bool.Parse(webpart.PropertyValuesCollection[pi.Name]);
                                }
                            }
                            catch (Exception)
                            { }
                        }
                        else if (pi.PropertyType.IsEnum)
                        {
                            DropDownList ddlPropertyValue = new DropDownList();
                            ddlPropertyValue.ID = ctrlID;
                            ddlPropertyValue.CssClass = "UserInput";
                            foreach (string ev in Enum.GetNames(pi.PropertyType))
                            {
                                ddlPropertyValue.Items.Add(ev);
                            }
                            EditorPartHelper.addToolPaneControl(sectionTableXsl, pi.Name + " (" + pi.PropertyType.Name + ")", ddlPropertyValue, false);
                            pvtbs.Add(pi.Name, ddlPropertyValue);

                            try
                            {

                                if (webpart.PropertyValuesCollection.ContainsKey(pi.Name))
                                {
                                    ListItem li = ddlPropertyValue.Items.FindByValue(webpart.PropertyValuesCollection[pi.Name]);
                                    if (li != null)
                                    {
                                        ddlPropertyValue.SelectedIndex = ddlPropertyValue.Items.IndexOf(li);
                                    }
                                }
                            }
                            catch
                            { }
                        }
                        else
                        {
                            TextBox tbPropertyValue = new TextBox();
                            tbPropertyValue.ID = ctrlID;
                            tbPropertyValue.CssClass = "UserInput";
                            tbPropertyValue.Text = null;
                            EditorPartHelper.addToolPaneControl(sectionTableXsl, pi.Name + " (" + pi.PropertyType.Name + ")", tbPropertyValue, false);

                            pvtbs.Add(pi.Name, tbPropertyValue);

                            try
                            {

                                if (webpart.PropertyValuesCollection.ContainsKey(pi.Name))
                                {
                                    tbPropertyValue.Text = webpart.PropertyValuesCollection[pi.Name];
                                }
                            }
                            catch
                            { }
                        }
                    }
                }
            }
            base.CreateChildControls();
        }

        public override void SyncChanges()
        {
            EnsureChildControls();

            UserControlHostingWebPart webpart = (UserControlHostingWebPart)this.WebPartToEdit;
            foreach (KeyValuePair<string, string> property in webpart.PropertyValuesCollection)
            {
                try
                {
                    Control pvtb = pvtbs[property.Key];
                    if (pvtb.GetType() == typeof(TextBox))
                    {
                        ((TextBox)pvtb).Text = property.Value;
                    }
                    else if (pvtb.GetType() == typeof(CheckBox))
                    {
                        ((CheckBox)pvtb).Checked = bool.Parse(property.Value);
                    }
                }
                catch (Exception)
                {
                }
            }
        }

        public override bool ApplyChanges()
        {
            EnsureChildControls();
            UserControlHostingWebPart webpart = (UserControlHostingWebPart)this.WebPartToEdit;
            webpart.PropertyValuesCollection.Clear();
            foreach (KeyValuePair<string, Control> pvtb in pvtbs)
            {
                try
                {
                    string postedvalue = HttpContext.Current.Request.Form[pvtb.Value.UniqueID];
                    if (pvtb.Value.GetType().Equals(typeof(TextBox)))
                    {
                        webpart.PropertyValuesCollection.Add(pvtb.Key, postedvalue);
                    }
                    else if (pvtb.Value.GetType().Equals(typeof(CheckBox)))
                    {
                        bool bv = false;
                        try
                        {
                            bv = bool.Parse(postedvalue);
                        }
                        catch
                        {
                            if (string.Equals(postedvalue, "on", StringComparison.InvariantCultureIgnoreCase))
                            {
                                bv = true;
                            }
                        }

                        webpart.PropertyValuesCollection.Add(pvtb.Key, bv.ToString());
                    }
                    else if (pvtb.Value.GetType().Equals(typeof(DropDownList)))
                    {
                        webpart.PropertyValuesCollection.Add(pvtb.Key, postedvalue);
                    }
                }
                catch
                {
                }
            }
            return true;
        }
    }
}
